namespace YM {
    export class ObjectPool{
        private readonly  dictionary:Map<{new()},ComponentQueue> = new Map<{new()},ComponentQueue>();

        public fetch<T extends Entity>(type:{new():T}):T
        {
            let queue=this.dictionary.get(type);
            let obj;
            if(queue==null){
                obj=new type();
            }
	        else if (queue.count == 0)
            {
	            obj =new type();
            }
            else
            {
                obj = queue.dequeue();
                //obj =new type();
            }
	        
            obj.isFromPool = true;
            obj.enabled=true;
            return obj;
        }
        
        public recycle(obj:Entity)
        {
            let type = obj.getType();
	        let queue:ComponentQueue=this.dictionary.get(type);
            if (queue==null)
            {
                queue = new ComponentQueue(type.Name);            

				this.dictionary.set(type, queue);
            }
            

	        // if (obj.node != null)
	        // {
		    //     obj.node.setParent(queue.node);
	        // }

            obj.id = 0;
            obj.enabled=false;
            queue.enqueue(obj);
        }

	    public dispose():void
	    {
		    for (let kv of this.dictionary)
		    {
			    kv[1].dispose();
		    }
		    this.dictionary.clear();
	    }
    }
    export class ComponentQueue {
        public id: number;
        
        private _typeName: string;
        public get typeName(): string {
            return this._typeName;
        }

        private readonly _queue: Queue<Entity> = new Queue<Entity>();

        constructor(typeName: string) {
            this.id = IdGenerater.GenerateInstanceId();
            this._typeName = typeName;
        }

        public enqueue(entity: Entity): void {
            this._queue.enqueue(entity);
        }

        public dequeue(): Entity {
            return this._queue.dequeue();
        }

        public peek(): Entity {
            return this._queue.peek();
        }
        public get queue(): Queue<Entity> {
            return this._queue;
        }

        public get count(): number {
            return this._queue.count;
        }

        public dispose(): void {
            while (this._queue.count > 0) {
                let component = this._queue.dequeue();
                component.dispose();
            }
        }
    }
}